package com.dark.util;

import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;

import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * ClassName: ThreadPoolUtil
 * Description:ThreadPoolUtil
 *
 * @author chengluchao
 * @date: 2023/4/17 4:48 PM
 * @since 1.4.25
 */
@Slf4j
public class ThreadPoolUtil {


    /**
     * <dt>IO密集型线程池</dt>
     * <br>
     * <dt>任务客户：</dt>
     * <dd>申请任务-消息通知</dd>
     */
    public static final ThreadPoolExecutor IO_INTENSIVE_EXECUTOR = new ThreadPoolExecutor(0, 5, 1, TimeUnit.HOURS, new LinkedBlockingQueue(1024));

    /**
     * 文件合并
     */
    public static final ThreadPoolExecutor FILE_MERGE_EXECUTOR = new ThreadPoolExecutor(2, 20, 1, TimeUnit.HOURS, new LinkedBlockingQueue(1024),
            new NamedThreadFactory("file-merge"));

    // 线程池的自我监控

    static {
        log.info("启动线程池监控");
        ScheduledExecutorService scheduledExec = Executors.newSingleThreadScheduledExecutor();
        scheduledExec.scheduleAtFixedRate(() -> {
            monitorThreadPool(FILE_MERGE_EXECUTOR, "文件合并");
        }, 10, 5, TimeUnit.SECONDS);
    }

    private static void monitorThreadPool(ThreadPoolExecutor executor, String executorName) {

        log.debug("{}-线程池监控：[Active threads：{},Completed tasks:{},Current pool size: {},Core pool size: {},Maximum pool size: {},Task queue size: {}]",
                executorName,
                executor.getActiveCount(),
                executor.getCompletedTaskCount(),
                executor.getPoolSize(),
                executor.getCorePoolSize(),
                executor.getMaximumPoolSize(),
                executor.getQueue().size()
        );
    }

    /**
     * 线程命名工程
     */
    public static class NamedThreadFactory implements ThreadFactory {
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String namePrefix;

        public NamedThreadFactory(String name) {
            namePrefix = name + "-thread-";
        }

        public Thread newThread(Runnable r) {
            Thread t = new Thread(r, namePrefix + threadNumber.getAndIncrement());
            return t;
        }
    }

}
